<?php

declare(strict_types=1);

namespace app\pac\controller;

use app\admin\model\IndexRule;
use app\admin\model\IndexUser;
use app\BaseController;
use League\Flysystem\Plugin\ForcedCopy;
use think\facade\Cache;
use think\facade\Env;
use think\facade\View;
use think\Request;

class Index extends BaseController
{
    public function read(Request $request)
    {

        $uid = $request->param('uid');

        $app_debug = Env::get('APP_DEBUG') ? 1 : 0;

        $pac_content_cache_key = 'pac_content_' . $uid;

        $content = Cache::get($pac_content_cache_key);


        if ($app_debug) {
            $content = false;
        }

        if (empty($content)) {

            $model_user = IndexUser::where('uid', $uid)->find();

            $pac_mode = $model_user->pac_mode;

            $list_rule = [];

            $list_rule_mine = IndexRule::where('user_id', $model_user->id)->where('status', '<>', 'disable')->column('content');

            $list_rule_system = IndexRule::where('public_status', 'apply')->column('content');

            $list_rule_others = IndexRule::where('user_id', '<>', $model_user->id)->where('status', 'public')->column('content');

            if ($pac_mode == 'default') {
                $list_rule = array_merge($list_rule, $list_rule_mine, $list_rule_system, $list_rule_others);
            } else if ($pac_mode == 'mine') {
                $list_rule = array_merge($list_rule, $list_rule_mine);
            } else if ($pac_mode == 'strict') {
                $list_rule = array_merge($list_rule, $list_rule_mine, $list_rule_system);
            }

            $list_rule = array_unique($list_rule);

            $list_rule_blocking = [];
            $list_rule_passing = [];

            foreach ($list_rule as  $rule_content) {
                if (substr($rule_content, 0, 2) !== '@@') {
                    $list_rule_passing[] = $rule_content;
                } else {
                    $list_rule_blocking[] = $rule_content;
                }
            }

            $this->initCharMap();

            $list_rule_blocking = $this->buildContentRule($list_rule_blocking);
            $list_rule_passing = $this->buildContentRule($list_rule_passing);


            View::assign('app_debug', 'var app_debug = ' . $app_debug);
            View::assign('letter_map', 'var letter_map = ' . json_encode($this->mapLetter));
            View::assign('number_map', 'var number_map = ' . json_encode($this->mapNumber));
            View::assign('list_rule_passing', "var list_rule_passing =[  {$list_rule_passing} ]");
            View::assign('list_rule_blocking', "var list_rule_blocking =[  {$list_rule_blocking} ]");
            View::assign('pac_proxy', $model_user->pac_proxy_output);

            $content = View::fetch(__DIR__ . '/../view/index/read.pac');

            Cache::set($pac_content_cache_key, $content, 3600);
        }


        if ($this->request->param('preview', 0) == 1) {
            dump($content);
            return '';
        }
        return response($content, 200)->contentType('application/x-ns-proxy-autoconfig');
    }

    protected function initCharMap()
    {

        // 字母数组
        $letters = range('a', 'z');
        $letters_password = range('a', 'z');

        // 打乱数组
        shuffle($letters_password);

        $letter_map = [];

        // 排除字母数组
        $letters_exclude = ['h', 't', 'p', 's'];

        foreach ($letters as $letter_index =>  $letter) {
            if (in_array($letter, $letters_exclude)) {
                $letter_map[$letter] = $letter;
                continue;
            }
            $letter_map[$letter] = $letters_password[$letter_index];
        }


        $numbers = range(0, 9);

        $numbers_password = range(0, 9);

        shuffle($numbers_password);

        $number_map = [];

        foreach ($numbers as $number_index =>  $number) {
            $number_map[$number] = $numbers_password[$number_index];
        }

        $this->mapNumber = $number_map;
        $this->mapLetter = $letter_map;
    }

    protected function buildContentRule($list_rule)
    {

        $app_debug = Env::get('APP_DEBUG');

        if (!$app_debug) {

            foreach ($list_rule as  &$rule_content) {
                $rule_content_arr = str_split( $rule_content);

                foreach ($rule_content_arr as &$cotnent_letter) {
                    if (isset($this->mapLetter[$cotnent_letter])) {
                        $cotnent_letter = $this->mapLetter[$cotnent_letter];
                    } else if (isset($this->mapNumber[$cotnent_letter])) {
                        $cotnent_letter = $this->mapNumber[$cotnent_letter];
                    }
                }

                $rule_content = implode('', $rule_content_arr);
            }
        }


        $content_rule = "\"";

        $list_rule_content = implode("\",\r\n    \"", $list_rule);

        $content_rule .= $list_rule_content;

        $content_rule .= "\"\r\n";



        $content_rule = str_replace('@', '', $content_rule);
        $content_rule = str_replace('|', '', $content_rule);
        $content_rule = str_replace('^', '', $content_rule);

        return $content_rule;
    }
}
